package com.ray.activiti.controller;


import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.TaskService;
import org.apache.log4j.Logger;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.ray.activiti.common.page.Page;
import com.ray.activiti.common.utils.ActUtils;
import com.ray.activiti.dto.ProcessNodeDto;
import com.ray.activiti.dto.ProcessTaskDto;
import com.ray.activiti.service.ActModelerService;
import com.ray.activiti.service.ExtendActFlowbusService;
import com.ray.activiti.service.ExtendActModelerService;
import com.ray.activiti.service.ExtendActNodesetService;
import com.ray.activiti.service.ExtendActTasklogService;
import com.ray.activiti.table.entity.ExtendActModel;
import com.ray.activiti.table.entity.ExtendActNodeset;
import com.ray.activiti.util.DataGridUtil;
import com.ray.activiti.vo.ActNode;
import com.ray.api.service.ActivitiApiService;
import com.ray.api.service.UcenterApiService;
import com.ray.auth.system.table.entity.Button;
import com.ray.common.util.ExceptionUtils;
import com.xiaoleilu.hutool.util.StrUtil;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.function.operator.PageDto;
import com.zjhc.flyhong.common.util.UUIDUtil;
import com.zjhc.flyhong.common.web.Result;
import com.zjhc.web.controller.WebController;

/**
 * 类的功能描述.
 * 流程办理相关操作
 * @Auther ray  qray686898@163.com
 * @Date 2017/12/28
 * @代码参考或来自  https://github.com/huangxianyuan/hxyFrame
 */
@Controller
@RequestMapping("act/deal")
public class ExtendActDealController extends WebController{
    private Logger log = Logger.getLogger(getClass());
    
    @Autowired
    UcenterApiService  ucenterApiService;
    @Autowired
    ActivitiApiService  activitiApiService;
    
    @Autowired
    ExtendActModelerService extendActModelService;

    @Autowired
    ActModelerService actModelerService;

    @Autowired
    ExtendActNodesetService nodesetService;

    @Autowired
    ExtendActTasklogService tasklogService;

    @Autowired
    TaskService taskService;

    @Autowired
    ExtendActFlowbusService flowbusService;

    /**
     * 测试
     * @param model
     * @param actModelEntity
     * @param request
     * @return
     */
    @RequestMapping("test")
    public ModelAndView test(String menuId,ModelAndView modelAndView, HttpServletRequest request){
    	LoginUser user = getLoginUser();
    	Result<Map<String, List<Button>>>  buttonsResult= ucenterApiService.queryUserButtonsWithMenu(user,menuId);
	  	if(buttonsResult.codeSuccess()){
	  		 modelAndView.addObject("buttons", buttonsResult.getData());
	  	}
	  	
	  	modelAndView.addObject("busId", UUIDUtil.getUUID());
	  	modelAndView.setViewName("activiti/test/view");
        return modelAndView;
    }
    
    /**
     * 启动流程
     * @param processTaskDto 完成任务dto
     * @return
     */
    @RequestMapping(value = "startFlow",method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Result<Object>> startFlow(String busId,String deployId,String defId,String userids,String actKey){
        try {
        	LoginUser user = getLoginUser();
            activitiApiService.startFlow(busId,actKey,userids,deployId,defId, user);
           return doSuccess("提交成功!");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }
    
    /**
     * 办理任务
     * @param processTaskDto 完成任务dto
     * @return
     */
    @RequestMapping(value = "handelTask",method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Result<Object>> handelTask(ProcessTaskDto taskDto){
        try {
        	LoginUser user = getLoginUser();
            activitiApiService.HandleTask(taskDto, user);
            return doSuccess("办理成功!");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }

    /**
     * 驳回到任务发起人，重新编辑提交
     * @param processTaskDto
     * @return
     */
    @RequestMapping(value = "backStartUser",method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Result<Object>> backStartUser(ProcessTaskDto processTaskDto,HttpServletRequest request){
    	LoginUser user = getLoginUser();
    	try {
    		activitiApiService.backStartUser(processTaskDto,user);
            return doSuccess("驳回到发起人,成功");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }


    /**
     * 我的待办页面
     * @param model
     * @param code
     * @param busId
     * @param request
     * @return
     */
    @RequestMapping("myUpcomingView")
    @RequiresPermissions("act:deal:myUpcoming:view")
    public ModelAndView myUpcoming(String menuId, HttpServletRequest request,ModelAndView modelAndView){
    	LoginUser user = getLoginUser();
    	  //查询页面拥有的资源
      Result<Map<String, List<Button>>>  buttonsResult= ucenterApiService.queryUserButtonsWithMenu(user,menuId);
  	  if(buttonsResult.codeSuccess()){
  		 modelAndView.addObject("buttons", buttonsResult.getData());
  	  }
  	  modelAndView.setViewName("activiti/deal/myUpcoming/view");
  	  return modelAndView;
    }
    
    
    /**
     * 我的待办列表
     * @param model
     * @param code
     * @param busId
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
	@RequestMapping("queryMyUpcoming")
    @RequiresPermissions("act:deal:myUpcoming:view")
    public  ResponseEntity<Map<String,Object>> queryMyUpcoming(Model model,String code,String busId, HttpServletRequest request){
    	 PageDto<ProcessTaskDto> pageDto= this.createJQPage(request);
    	 LoginUser user = getLoginUser();
    	 int pageNum = pageDto.getPage();
        Map<String,Object> params = new HashMap<>();
        params.put("code",code);
        params.put("busId",busId);
        Page<ProcessTaskDto> page = actModelerService.findMyUpcomingPage(params, pageNum,user);
        List<ProcessTaskDto> list = page.getResult();
        for(ProcessTaskDto actModel :list){
       	 actModel.setStartUserName(ucenterApiService.queryUserName(actModel.getStartUserId()));
       	 actModel.setDealName(ucenterApiService.queryUserName(actModel.getDealId()));
        } 
   	    pageDto.setRecords(list);
   	    pageDto.setTotal(page.getTotal());
		return doSuccess(DataGridUtil.dataConvert(pageDto));
    }
    
    
    /**
     * 办理
     * @param menuId
     * @param taskDto
     * @param request
     * @param modelAndView
     * @return
     * @throws IOException 
     */
    @RequestMapping("toDoView")
    @RequiresPermissions("act:deal:myUpcoming:todo")
    public ModelAndView toDoView(String menuId,ProcessTaskDto taskDto,  HttpServletRequest request,ModelAndView modelAndView) throws IOException{
    	LoginUser user = getLoginUser();
    	  //查询页面拥有的资源
      Result<Map<String, List<Button>>>  buttonsResult= ucenterApiService.queryUserButtonsWithMenu(user,menuId);
  	  if(buttonsResult.codeSuccess()){
  		 modelAndView.addObject("buttons", buttonsResult.getData());
  	  }
  	  //获取下个节点信息
      List<ProcessNodeDto> nextActNodes = actModelerService.getNextActNodes(taskDto);
      if(!nextActNodes.isEmpty()){
    	  modelAndView.addObject("nextActNode", nextActNodes.get(0));
      }
      //当前节点信息
      ExtendActNodeset nodesetEntity = actModelerService.getNodeSetByTaskId(taskDto.getTaskId());
      ExtendActModel actModel = extendActModelService.queryByModelId(nodesetEntity.getModelId());
      //流程第一个节点
      ActNode node = actModelerService.getStartFlowInfo(actModel.getDeploymentId());
      if(StrUtil.isNotBlank(nodesetEntity.getDetailUrl())){
    	  //可以支持传业务ID
    	  modelAndView.addObject("detailUrl", nodesetEntity.getDetailUrl().replace("{busId}", taskDto.getBusId()));
      }else{
    	  modelAndView.addObject("detailUrl", nodesetEntity.getDetailUrl());
      }
      
      modelAndView.addObject("taskDto", taskDto);
      if(StrUtil.equals(node.getNodeId(), nodesetEntity.getNodeId())){
    	  modelAndView.setViewName("activiti/deal/myUpcoming/mytodo");
      }else{
    	  modelAndView.setViewName("activiti/deal/myUpcoming/todo"); 
      }
  	  return modelAndView;
    }  
    
    
    /**
     * 我的已办页面
     * @param model
     * @param code
     * @param busId
     * @param request
     * @return
     */
    @RequestMapping("myDoListView")
    @RequiresPermissions("act:deal:myDoList:view")
    public ModelAndView myDoListView(String menuId, HttpServletRequest request,ModelAndView modelAndView){
    	LoginUser user = getLoginUser();
    	  //查询页面拥有的资源
      Result<Map<String, List<Button>>>  buttonsResult= ucenterApiService.queryUserButtonsWithMenu(user,menuId);
  	  if(buttonsResult.codeSuccess()){
  		 modelAndView.addObject("buttons", buttonsResult.getData());
  	  }
  	  modelAndView.setViewName("activiti/deal/myDoList/view");
  	  return modelAndView;
    }
    
    
    /**
     * 我的待办列表
     * @param model
     * @param code
     * @param busId
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
	@RequestMapping("queryMyDoList")
    @RequiresPermissions("act:deal:myDoList:view")
    public  ResponseEntity<Map<String,Object>> queryMyDoList(Model model,String code,String busId, HttpServletRequest request){
    	 PageDto<ProcessTaskDto> pageDto= this.createJQPage(request);
    	 LoginUser user = getLoginUser();
    	 int pageNum = pageDto.getPage();
        Map<String,Object> params = new HashMap<>();
        params.put("code",code);
        params.put("busId",busId);
        Page<ProcessTaskDto> page = actModelerService.myDonePage(params, pageNum,user);
        List<ProcessTaskDto> list = page.getResult();
        for(ProcessTaskDto actModel :list){
       	 actModel.setStartUserName(ucenterApiService.queryUserName(actModel.getStartUserId()));
       	 actModel.setDealName(ucenterApiService.queryUserName(actModel.getDealId()));
        } 
   	    pageDto.setRecords(list);
   	    pageDto.setTotal(page.getTotal());
		return doSuccess(DataGridUtil.dataConvert(pageDto));
    }
    
    /**
     * 获取实时流程图
     * @param processInstanceId 流程实例
     * @return
     */
    @RequestMapping(value = "flowImgView",method = RequestMethod.GET)
    @ResponseBody
    @RequiresPermissions("act:deal:myUpcoming:pic")
    public Result<Object> showFlowImg(String processInstanceId, HttpServletResponse response){
        try {
            InputStream inputStream = ActUtils.getFlowImgByInstantId(processInstanceId);
            //输出到页面
            byte[] b = new byte[1024];
            int len;
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        } catch (IOException e) {
        	log.error(e.getLocalizedMessage());
        }
        return null;
    }
    
    /**
     * 我的已办页面
     * @param model
     * @param code
     * @param busId
     * @param request
     * @return
     */
    @RequestMapping("toTurnView")
    @RequiresPermissions("act:deal:toTurn:view")
    public ModelAndView toTurnView(String menuId,ProcessTaskDto processTaskDto,String taskId, HttpServletRequest request,ModelAndView modelAndView){
    	LoginUser user = getLoginUser();
    	  //查询页面拥有的资源
      Result<Map<String, List<Button>>>  buttonsResult= ucenterApiService.queryUserButtonsWithMenu(user,menuId);
  	  if(buttonsResult.codeSuccess()){
  		 modelAndView.addObject("buttons", buttonsResult.getData());
  	  }
  	 //当前节点信息
      ExtendActNodeset nodesetEntity = actModelerService.getNodeSetByTaskId(taskId);
      modelAndView.addObject("detailUrl", nodesetEntity.getDetailUrl());
  	  modelAndView.addObject("taskDto",processTaskDto);
  	  modelAndView.setViewName("activiti/deal/toTurn/view");
  	  return modelAndView;
    }

   
    /**
     * 转办
     * @param processTaskDto
     * @return
     */
    @RequestMapping(value = "turnToDo",method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("act:deal:toTurn:view")
    public ResponseEntity<Result<Object>> turnToDo(ProcessTaskDto processTaskDto,String toUserId,HttpServletRequest request){
        try {
        	LoginUser user = getLoginUser();
        	activitiApiService.turnToDo(processTaskDto,toUserId,user);
            return doSuccess("转办任务,成功");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }
    
    /**
     * 返回上一节点
     * @param processTaskDto
     * @return
     */
    @RequestMapping(value = "backPreviousNode",method = RequestMethod.POST)
    @ResponseBody
    @RequiresPermissions("act:deal:backPreviousNode")
    public ResponseEntity<Result<Object>> backPreviousNode(ProcessTaskDto processTaskDto,HttpServletRequest request){
        try {
        	LoginUser user = getLoginUser();
        	boolean flag = actModelerService.hasPreNode(processTaskDto, user);
        	if(!flag){
        		return doError("当前节点不能返回上一级");
        	}
        	//判断是否返回上节点
        	actModelerService.backPreviousNode(processTaskDto,user);
            return doSuccess("返回上节点,成功");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }
    /**
     * 停止流程
     * @param processTaskDto
     * @return
     */
    @RequestMapping(value = "stop",method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Result<Object>> stop(ProcessTaskDto processTaskDto,HttpServletRequest request){
        try {
        	LoginUser user = getLoginUser();
        	actModelerService.stopFlow(processTaskDto,new HashMap<>(),user);
            return doSuccess("取消流程,成功");
        } catch (Exception e) {
            return doError(ExceptionUtils.getExceptionAllinformation(ExceptionUtils.unwrap(e).getLocalizedMessage()));
        }
    }
    
}
